﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using BSF.BaseService.MonitorPlatform.Model;
using BSF.Log;
using BSF.ServicesResult;
using BSF.Tool;
using Newtonsoft.Json;

namespace HuntingFishGame.CustomerApi
{
    /// <summary>
    /// WebApi耗时
    /// </summary>
    public class TimingActionFilter : ActionFilterAttribute
    {
        private const string Key = "__action_duration__";

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (SkipLogging(actionContext))
            {
                return;
            }

            var stopWatch = new Stopwatch();
            actionContext.Request.Properties[Key] = stopWatch;
            stopWatch.Start();
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (!actionExecutedContext.Request.Properties.ContainsKey(Key))
            {
                return;
            }

            var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch;



            if (stopWatch != null)
            {
                stopWatch.Stop();
                var controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
                var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
                Debug.Print(string.Format("[Execution of {0}/{1} took {2}.]", controllerName, actionName, stopWatch.Elapsed));

                try
                {
                    double execTime = stopWatch.Elapsed.TotalMilliseconds;
                    if (actionExecutedContext.Response != null)
                    {
                        var objectContent = actionExecutedContext.Response.Content as ObjectContent;
                        if (objectContent != null)
                        {
                            var type = objectContent.ObjectType; //type of the returned object
                            var value = objectContent.Value; //holding the returned value

                            var result = value as IApiResult;
                            if (result != null)
                            {
                                result.ExcuteTime = execTime;
                            }

                            #region API调用日志

                            //if (bool.Parse(BSFConfig.IsOpenTimeWatchLogSwitch))
                            //{
                            var req = CommonHelper.GetRequest();//获取请求
                            if (req != null)
                            {
                                var param = new BindParameter();
                                CommonHelper.ParamBinds(req, ref param);

                                param.dict = new Dictionary<string, string>();
                                NameValueCollection entityProperties = null;
                                if (req.Form.HasKeys())
                                {
                                    entityProperties = req.Form;//req.Params
                                }
                                else
                                {
                                    entityProperties = req.QueryString;
                                }
                                if (entityProperties.HasKeys())
                                {
                                    foreach (string tempkey in entityProperties.Keys)
                                    {
                                        param.dict.Add(tempkey, entityProperties[tempkey]);
                                    }
                                }
                                param.RequseUrl = req.Url.AbsoluteUri;

                                //TODO 写耗时日志,通过任务持久化到数据库
                                var key = Guid.NewGuid().ToString("D");
                                string msg = string.Format("request:{0}", JsonConvert.SerializeObject(param) ?? "");
                            }
                            //}

                            #endregion
                        }
                    }
                }
                catch (Exception ex)
                {

                    ErrorLog.Write(string.Format("请求:{0}/{1},耗时日志抓取异常", controllerName, actionName), ex);
                    ErrorLog.Write(
                        string.Format("Response:{0}",
                            actionExecutedContext.Response == null
                                ? "null"
                                : JsonConvert.SerializeObject(actionExecutedContext.Response)), null);
                }
            }
        }

        #region method

        private static bool SkipLogging(HttpActionContext actionContext)
        {
            return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() ||
                    actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any();
        }

        #endregion
    }
}